import BaseController from "./controller"
import _ from 'lodash'
import request from '@/utils/request'

class WorkflowController extends BaseController {

  processSave(postModel, url, isSend) {
    return this.save(postModel, url, isSend);
  }

  save(postModel = this.context.models, url, isSend = false) {
    return new Promise((resolve, reject) => {
      if (!url) {
        url = this.appendPrimaryKey(isSend ? this.context.urls.processRun : this.context.urls.processSave)
      }

      if (postModel == undefined || url == undefined) {
        this.afterSave(false, {
          message: 'PostModel或者URL不可为undefined'
        });
      } else {

        postModel = _.cloneDeep(postModel);

        if (this.onBeforeSave(postModel) === false) {
          return;
        }
        if (isSend && this.onBeforeSend(postModel) === false) {
          return;
        }
        url = this.appendWorkflowArgs(url);
        postModel.pageAction = this.context.pageAction;
        if (isSend) {
          if (this.context.controlData.workflow.needChoose) {
            if (!postModel.choice.users) {
              this.vm.notifyError("请选择处理人");
              return;
            }
            if (!postModel.choice.tran || !postModel.choice.activity) {
              this.vm.notifyError("请选择处理环节");
              return;
            }
          }
        }

        let loading = this.vm.appLoading('正在执行...', this.vm.$root.$el);
        //let loading = this.vm.notifyInfo('正在执行...');
        request({
          url: url,
          method: 'post',
          data: postModel
        }).then(r => {
          loading.close();
          if (!isSend) {
            _.extend(this.context.models, r.parameters.models || {});
          }
          this.afterSave(r.success, r, isSend);
          if (isSend) {
            this.onAfterSend(r.success, r)
          }
          resolve(r);
        }).catch(e => {
          loading.close();
          this.afterSave(false, e, isSend);
          if (isSend) {
            this.onAfterSend(false, e)
          }
          reject();
        });
      }
    });
  }

  afterSave(isSuccess, result, isSend) {
    let msg
    if (isSuccess) {
      if (result.parameters && this.context.pageAction == 'create') {
        this.context.pageAction = "edit";
        this.context.models.pageAction = "edit";
        this.context.pageActionText = "编辑";
        this.context.primaryKey = result.parameters.primaryKey || {};
        this.context.controlData.workflow.taskId = result.parameters.taskId;
        this.context.controlData.workflow.instanceId = result.parameters.instanceId;
      }
      msg = result.message || (isSend ? '发送成功' : '保存成功');
      if (result.parameters.nextHandlers) {
        let nestHandler = result.parameters.nextHandlers.join(",");
        if (nestHandler)
          msg += "下一环节处理人：" + nestHandler;
      }
      //this.vm.notifySuccess(msg);
      this.onAfterSave(isSuccess, result);
      this.vm.$alert(msg, '提示', {
        type: 'success'
      }).then(() => {
        this.vm.$root.closeModal();
      })
    } else {
      msg = result.message || (isSend ? "发送失败" : "保存失败");
      this.vm.$alert(msg, '提示', {
        type: 'warning'
      })
      //this.vm.notifyError(msg);
    }
  }
  onBeforeSend(postModel) {
    return true;
  }
  onAfterSend(isSuccess, result) {
    if (isSuccess) {
      this.vm.$root.closeModal();
    }
  }
  appendWorkflowArgs(url) {
    let args = {
      appCode: this.context.controlData.workflow.appCode,
      version: this.context.controlData.workflow.version,
      taskId: this.context.controlData.workflow.taskId,
      assigneeId: this.context.controlData.workflow.assigneeId
    };
    for (let o in args) {
      if (!args[o]) continue;
      let joinChar = url.indexOf("?") == -1 ? "?" : "&";
      url += joinChar;
      url += o + "=" + args[o];
    }
    return url;
  }

  appendPrimaryKey(url, primaryKey) {
    if (!url) {
      return undefined;
    } else {
      for (let o in primaryKey) {
        let v = primaryKey[o];
        if (v != undefined) {
          let joinChar = url.indexOf("?") == -1 ? "?" : "&";
          url += joinChar;
          url += o + "=" + (primaryKey[o] || "");
        }
      }
      return url;
    }
  }

  // 删除
  processDelete() {
    return new Promise((rs, rj) => {
      this.vm.$confirm("确定要删除当前事项吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        let url = this.context.urls.processDelete;
        url = url + "?appCode=" + this.context.controlData.workflow.appCode;
        url = url + "&taskId=" + this.context.controlData.workflow.taskId;
        url = url + "&assigneeId=" + (this.context.controlData.workflow.assigneeId || "");
        url = this.appendPrimaryKey(url, this.context.primaryKey);

        return this.getRequestPromise(url, {})
          .then((r) => {
            if (r && r.success) {
              this.vm.notifySuccess("删除成功");
              rs();
            } else {
              this.vm.notifyError((r || {}).message || "删除失败");
              rj();
            }
          })
          .catch((r) => {
            this.vm.notifyError((r || {}).message || "删除失败");
            rj();
          });
      });
    });
  }

  // 撤回
  processRollback() {
    return new Promise((rs, rj) => {
      this.vm.$confirm("确定要撤回此事项码？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        let url = this.context.urls.processRollback;
        url = url + "?pageAction=view&appCode=" + this.context.controlData.workflow.appCode;
        url = url + "&historyTaskId=" + this.context.controlData.workflow.historyTaskId;
        url = url + "&assigneeId=" + (this.context.controlData.workflow.assigneeId || "");
        url = url + "&version=" + this.context.controlData.workflow.version;
        url = this.appendPrimaryKey(url, this.context.primaryKey);

        return this.getRequestPromise(url, {})
          .then((r) => {
            if (r && r.success) {
              this.vm.notifySuccess("撤回成功");
              rs();
            } else {
              this.vm.notifyError((r || {}).message || "撤回失败");
              rj();
            }
          })
          .catch((r) => {
            this.vm.notifyError((r || {}).message || "撤回失败");
            rj();
          });
      });
    });
  }

  // 退回
  processBackward() {
    return new Promise((rs, rj) => {
      this.vm.$prompt("请填写你的意见", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      }).then(({
        value
      }) => {
        let url = this.context.urls.processBackward;
        url = url + "?pageAction=edit&appCode=" + this.context.controlData.workflow.appCode;
        url = url + "&taskId=" + this.context.controlData.workflow.taskId;
        url = url + "&version=" + this.context.controlData.workflow.version;
        url = url + "&assigneeId=" + (this.context.controlData.workflow.assigneeId || "");
        url = this.appendPrimaryKey(url, this.context.primaryKey);

        return this.getRequestPromise(url, {
            workflowComment: value
          })
          .then((r) => {
            if (r && r.success) {
              this.vm.notifySuccess("回退成功");
              rs();
            } else {
              this.vm.notifyError((r || {}).message || "回退失败");
              rj();
            }
          })
          .catch((r) => {
            this.vm.notifyError((r || {}).message || "回退失败");
            rj();
          });
      });
    });
  }

  // 退回到指定环节
  processJump(params) {
    let url = this.context.urls.processRollbackAssign;
    url = url + "?pageAction=edit&appCode=" + this.context.controlData.workflow.appCode;
    url = url + "&taskId=" + this.context.controlData.workflow.taskId;
    url = url + "&version=" + this.context.controlData.workflow.version;
    url = url + "&assigneeId=" + (this.context.controlData.workflow.assigneeId || "");
    url = this.appendPrimaryKey(url, this.context.primaryKey);

    return this.getRequestPromise(url, {
        targetActivityId: params.selectTask,
        workflowComment: params.sendComment
      })
      .then((r) => {
        if (r && r.success) {
          this.vm.$alert("回退成功");
        } else {
          this.vm.$alert((r || {}).message || "回退失败");
        }
      })
      .catch((r) => {
        this.vm.$alert((r || {}).message || "回退失败");
      });
  }

  // 终止
  processTerminate() {
    return new Promise((rs, rj) => {
      this.vm.$prompt("请填写你的终止意见", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
        })
        .then(({
          value
        }) => {
          let url = `${this.context.urls.processTerminate}?pageAction=edit&appCode=${
              this.context.controlData.workflow.appCode
            }&version=${
              this.context.controlData.workflow.version
            }&taskId=${this.context.controlData.workflow.taskId}&assigneeId=${
              this.context.controlData.workflow.assigneeId || ""
            }&instanceId=${this.context.controlData.workflow.instanceId}`;

          url = this.appendPrimaryKey(url, this.context.primaryKey);

          return this.getRequestPromise(url, {
              workflowComment: value
            })
            .then((r) => {
              if (r && r.success) {
                this.vm.notifySuccess("终止成功");
                rs();
              } else {
                this.vm.notifyError((r || {}).message || "终止失败");
                rj();
              }
            })
            .catch((r) => {
              this.vm.notifyError((r || {}).message || "终止失败");
              rj();
            });
        })
        .catch(() => {});
    });
  }

  // 传阅
  processDoNotify(users) {
    return new Promise((rs, rj) => {
      let userIds = users.map((u) => {
        return u.userId;
      }).join(',');
      let url = this.context.urls.processDoNotify;
      url = url + "?appCode=" + this.context.controlData.workflow.appCode;
      url = url + "&taskId=" + this.context.controlData.workflow.taskId;
      url = url + "&assigneeId=" + (this.context.controlData.workflow.assigneeId || '');

      this.getRequestPromise(url, {
        users: userIds
      }).then(r => {
        if (r && r.success) {
          this.vm.notifySuccess("传阅成功！");
          rs();
        } else {
          this.vm.notifyError("传阅失败！");
          rj();
        }
      }).catch(r => {
        this.vm.notifyError((r || {}).message || "传阅失败！");
        rj();
      });
    });
  }

  // 已阅
  processNotify() {
    return new Promise((rs, rj) => {
      let url = this.context.urls.processNotify;
      url = url + "?appCode=" + this.context.controlData.workflow.appCode;
      url = url + "&taskId=" + this.context.controlData.workflow.taskId;
      url = url + "&assigneeId=" + (this.context.controlData.workflow.assigneeId || '');
      this.getRequestPromise(url, {}).then(r => {
        if (r && r.success) {
          this.vm.notifySuccess("已阅操作成功！");
          rs();
        } else {
          this.vm.notifyError("已阅操作失败！");
          rj();
        }
      }).catch(r => {
        this.vm.notifyError((r || {}).message || "已阅操作失败！");
        rj();
      });
    });
  }

  getRequestPromise(url, params, method = 'post') {
    let data = method.toLowerCase() === 'post' ? {
      data: params
    } : {
      params: params
    };
    return new Promise((rs, rj) => {
      request({
          url: url,
          method: method,
          ...data
        })
        .then((rlt) => {
          rs(rlt);
        })
        .catch((rlt) => {
          rlt.message = "获取数据失败，请稍后重试";
          rj(rlt);
        });
    });
  }

  static
  export (options) {
    let superOptions = super.export(options);
    superOptions.methods = _.extend({}, {
      processSave(postModel, url, isSend) {
        return this.super.save(postModel, url, isSend);
      },
      // processSend() {

      // },
      processDoNotify(users = []) {
        return this.super.processDoNotify(users);
      },
      processNotify() {
        return this.super.processNotify();
      },
      processRollback() {
        return this.super.processRollback();
      },
      processBackward() {
        return this.super.processBackward();
      },
      processDelete() {
        return this.super.processDelete();
      },
      processTerminate() {
        return this.super.processTerminate();
      },
      processJump() {
        return this.super.processJump();
      },

    }, superOptions.methods);
    return superOptions;
  }
}

export default WorkflowController;
